Sarue.XHR = new Class({
	request	: {},
	
	construct: function(options)
	{
		this.initializeRequest();
	},
	
	initializeRequest : function()
	{
		this.request = this.self.GetXmlHttp();
      	this.request.onreadystatechange = this.onStateChange;
		
		var data = this.self.parseData(this.options.data, this.options.noCache);
		
		if(data && this.options.method.toUpperCase() == 'GET'){
			var url = (this.options.url + ((this.options.url.search(/\?/) != -1) ? '&' : '?')) + data;
			var data = null;
		}
		else{
			var url = this.options.url;
		}
		
		this.request.open(this.options.method.toUpperCase(), url, this.options.async);
		
		if (this.options.urlEncoded) {
			var rpl =  this.options;
				rpl.dataLength = data ? data.length : '';
				
			for (var key in this.options.headers) {
				this.setRequestHeader(key, Sarue.Tools.srpl(this.options.headers[key], rpl));
			}
		}
		
		this.self.requests.push(this.request);
		
		this.send(data);
	},
	
	setRequestHeader : function(key, value)
	{
		try {
			return (this.request && value) ? this.request.setRequestHeader(key, value) : null;
		}catch(e){
			return null;
		}
	},
	
	onStateChange : function(e){
		switch (this.request.readyState)
		{
		 case 0:
		    this.self.wait(this.options.timeout);
		    this.onUninitialize();
		    break;
		                       
		 case 1:
		    this.self.wait(this.options.timeout);
		    this.onLoading();
		    break;
		                       
		 case 2:
		    this.self.wait(this.options.timeout);
		    this.onLoaded();
		    break;
		               
		 case 3:
		    this.self.wait(this.options.timeout);
		    this.onInteractive();
		    break;
		                       
		 case 4:
		    if (this.request.status == 200)
		       this.onSuccess();
		    else
		       this.onFailure();
			   
		    this.onComplete();
		    break;
		}
	},
	
	send : function(data)
	{
		return (this.request) ? this.request.send(data) : null;
	},
	
	close : function()
	{
		return (this.request) ? this.request.abort() : null;
	},
	
	getResponseXML : function()
	{
		return (this.request) ? this.request.responseXML : null;
	},
	
	getResponseHTML : function()
	{
		var text = this.getResponseText();
		var convert = document.createElement('root');
			convert.innerHTML = text;
		
		return convert.childNodes;
	},
	
	getResponseText : function()
	{
		return (this.request) ? this.request.responseText : null;
	},
	
	onUninitialize : function()
	{
		this.options.onUninitialize.apply(this);
	},
	onLoading : function()
	{
		this.options.onLoading.apply(this);
	},
	onLoaded : function()
	{
		this.options.onLoaded.apply(this);
	},
	onInteractive : function()
	{
		this.options.onInteractive.apply(this);
	},
	onSuccess : function()
	{
		this.options.onSuccess.apply(this, [this.getResponseText(), this.getResponseXML()]);
	},
	onFailure : function()
	{
		var code = this.request.status;
		
		this.options.onFailure.apply(this, [code]);
		
		if(this.options.onErrors[code])
			this.options.onErrors[code].apply(this);
	},
	onComplete: function()
	{
		this.options.onComplete.apply(this);
	}
	
},{
	requests: [],
	
	defaults : {
		url: null,
		data: null,
		method: 'GET',
		encoding: 'UTF-8',
		timeout: 0,
		noCache: true,
		urlEncoded:true,
		async:true,
		
		onUninitialize 	: function(){},
		onLoading 		: function(){},
		onLoaded  		: function(){},
		onInteractive 	: function(){},
		onSuccess 		: function(){},
		onFailure 		: function(){},
		onComplete 		: function(){},
		onErrors		: {},
		
		headers: {
			'Content-Type': 'application/x-www-form-urlencoded; charset={encoding}',
			'X-Requested-With': 'XMLHttpRequest',
			'Accept': 'text/javascript, text/html, application/xml, text/xml, */*',
			'Content-length': '{dataLength}'
		}
	},
	
	setDefault: function(defaults){
		console.info(this);
		for (var key in defaults) {
			this.defaults[key] = defaults[key];
		}
	},
	
	GetXmlHttp: function(){
		if (window.XMLHttpRequest)
			var xmlHttp = new XMLHttpRequest();
		
		else if(window.ActiveXObject)
			var xmlHttp = ActiveXObject('Microsoft.XMLHTTP');
			
		return xmlHttp;
	},
	
	parseData: function(parans, noCache){
		var data = [];
		parans = parans || {};
		
		if(noCache)
			parans.noCache = new Date().getTime();
		
		for(var key in parans)
			data.push(key + '=' + parans[key])
			
		return data.join('&');
	},
	
	wait: function(timeout){
		window.setTimeout("void(0)", timeout);
	}
});